var _isOpenRequired = false;
function isFormatValid(formId) {
    _isOpenRequired = false;

    var _isValid = _validator[formId].form();
    if (!_isValid) {
        _validator[formId].focusInvalid(formId)
    }
    return _isValid;
}


function isValid(formId) {
    _isOpenRequired = true;

    var _isValid = _validator[formId].form();
    if (!_isValid) {
        _validator[formId].focusInvalid(formId)
    }
    return _isValid;
}

function findDisplayElement(_element) {
    if ('multiselect' == _element.data("cust-type")) {
        return $("#" + _element.data("relate-id"));
    }
    if ('tautocomplete' == _element.data("cust-type")) {
        return $("[id='" + _element.data("relate-id") + "']");
    }

    if ('key' == _element.attr("autotype")) {
        return _element.closest("span").find('input[autotype="match"]');
    }

    if (_element.attr("type") == 'text' || _element[0].nodeName == 'TEXTAREA') {
        return _element;
    }

    if (_element.attr("type") == 'checkbox' || _element[0].nodeName == 'radio') {
        return $(_element[0]);
    }

    return null;
}
var _layer_index;
function showErrorMsg(formId, _displayElement) {

    var _parent = !_displayElement.attr('name') ? "form[id='" + formId + "'] [id='" + _displayElement.attr('id') + "']"
        : "form[id='" + formId + "'] [name='" + _displayElement.attr('name') + "']";

    _layer_index = layer.tips(_validator[formId].errorList[0].message,
        _parent,
        {
            tips: [1, '#b94a48'],
            time: 0
        });
}

$.validator.prototype.optional = function (element) {
    var val = this.elementValue(element);
    return !$.validator.methods.isNotEmpty.call(this, val, element) && "dependency-mismatch";
}

$.validator.prototype.focusInvalid = function (formId) {
    if (this.settings.focusInvalid) {
        try {
            var _element = $(this.errorList.length && this.errorList[0].element);
            var _displayElement = findDisplayElement(_element);

            if ('multiselect' == _element.data("cust-type")) {
                _displayElement
                    .focus()
                    // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
                    .trigger("focusin");
            }
            if ('tautocomplete' == _element.data("cust-type")) {
                _displayElement
                    .focus()
                    // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
                    .trigger("focusin");
            }

            if ('key' == _element.attr("autotype")) {
                _displayElement
                    .focus()
                    // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
                    .trigger("focusin");
            }

            if (_element.attr("type") == 'text' || _element[0].nodeName == 'TEXTAREA'
                || _element.attr("type") == 'checkbox' || _element.attr("type") == 'radio') {
                if (!_element.attr("readonly")) {
                    _displayElement
                        .focus()
                        // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
                        .trigger("focusin");
                }


            }
            if (_displayElement != null) {
                showErrorMsg(formId, _displayElement);
            }

            return;

        } catch (e) {
            // ignore IE throwing errors when focusing hidden elements
        }
    }
}

function isNotEmpty(value, element, param) {

    // check if dependency is met
    if (!this.depend(param, element)) {
        return "dependency-mismatch";
    }
    if (element.nodeName.toLowerCase() === "select") {
        // could be an array for select-multiple or a string, both are fine this way
        var val = $(element).val();
        return val && val.length > 0;
    }
    if (this.checkable(element)) {
        return this.getLength(value, element) > 0;
    }
    return value.length > 0;
}
// 固话
function telephone(value, element, param) {
    return value ? /^([0]\d{2,3}-)?(\d{7,8})(-\d{3,})?$/.test($.trim(value)) : true;
}

// 手机
function mobilephone(value, element, param) {
    return value ? /^([0]?[1-9])\d{10}$/.test($.trim(value)) : true;
}
// 手机或固话
function phone(value, element, param) {
    return value ? (mobilephone(value, element, param) || telephone(value, element, param)) : true;
}

function validateRequired(value, element, param) {

    if (!_isOpenRequired) {
        return true;
    }

    // check if dependency is met
    if (!this.depend(param, element)) {
        return "dependency-mismatch";
    }
    if (element.nodeName.toLowerCase() === "select") {
        // could be an array for select-multiple or a string, both are fine this way
        var val = $(element).val();
        return val && val.length > 0;
    }
    if (this.checkable(element)) {
        return this.getLength(value, element) > 0;
    }
    return value.length > 0;
}

function validateRelate(value, element, param) {
    if ($("input[name='" + param['name'] + "']").val().length <= 0) {
        return true;
    }
    return value.length > 0;
}

function validateMaxBytes(value, element, param) {
    var realLength = 0;
    for (var i = 0; i < value.length; i++) {
        var charCode = value.charCodeAt(i);
        if (charCode >= 0 && charCode <= 128) {
            realLength += 1;
        } else {
            // 如果是中文则长度加2
            realLength += 2;
        }
    }
    return this.optional(element) != false || (realLength <= param);
}

function validateIsNumber(value, element, param) {
    if (param) {
        var reg = new RegExp("^(0(.\\d+)?|[1-9]\\d*(.\\d+)?)$");
        return this.optional(element) != false || reg.test(value);
    }

    return true;
}

function validateMaxNumber(value, element, param) {

    var integer = param[0];
    var decimal = param[1] || 0;

    var reg = decimal > 0 ? new RegExp("^\\d{1," + (integer * 1 - decimal * 1) + "}([.]\\d{1," + decimal + "})?$")
        : new RegExp("^\\d{1," + integer + "}$");

    $.validator.messages["maxNum"] = decimal > 0 ? "最多输入" + (integer * 1 - decimal * 1) + "个整数位," + decimal + "个小数位" : "最多输入" + integer + "个数字";
    return this.optional(element) != false || reg.test(value);
}

function validateRule(value, element, param) {

    if (!param.Nullable) {
        var result = $.validator.methods.required.call(this, value, element);
        if (!result) {
            $.validator.messages["rule"] = "这是必填项";
            return false;
        }
    }

    $.validator.messages["rule"] = param.Demo;
    return this.optional(element) != false || new RegExp(param.Pattern).test(value);
}

function validateToggleRule(value, element, param) {

    var toggleStatus = param["toggle"]();
    if ("Z" == toggleStatus) {
        return _validateToggleRule.call(this, value, element, param["Z"]);
    }

    if ("C" == toggleStatus) {
        return _validateToggleRule.call(this, value, element, param["C"]);
    }

    if ("I" == toggleStatus) {
        return _validateToggleRule.call(this, value, element, param["I"]);
    }

    return _validateToggleRule.call(this, value, element, {});
}

function _validateToggleRule(value, element, param) {
    if (!param.Nullable) {
        var result = $.validator.methods.required.call(this, value, element);
        if (!result) {
            $.validator.messages["toggleRule"] = "这是必填项";
            return false;
        }
    }

    if (param.maxBytes) {
        var result = $.validator.methods.maxBytes.call(this, value, element, param.maxBytes);
        if (!result) {
            $.validator.messages["toggleRule"] = $.validator.format($.validator.messages["maxBytes"], param.maxBytes);
            return false;
        }
    }

    if (param.maxNum) {
        var result = $.validator.methods.maxNum.call(this, value, element, param.maxNum);
        if (!result) {
            $.validator.messages["toggleRule"] = $.validator.format($.validator.messages["maxNum"], param.maxNum);
            return false;
        }
    }

    if (param.Pattern) {
        $.validator.messages["toggleRule"] = param.Demo;
        return this.optional(element) != false || new RegExp(param.Pattern).test(value);
    }

    return true;
}

var _validator = {};
function formValidate(formId, rules, isOpenRequired) {

    for (var key in rules) {
        var minlength = rules[key].minlength;
        if (minlength && minlength >= 1) {
            try {
                var titleTD = $("#" + formId + " [name='" + key + "']").closest("TD").prev();
                if (!titleTD.html().startWith("<span")) {
                    titleTD.html("<span style='color:red!important'>*</span>" + titleTD.html());
                }

                rules[key].required = true;
            }
            catch (e) {

            }

        }
        else if (rules[key].required) {
            var titleTD = $("#" + formId + " [name='" + key + "']").closest("TD").prev();
            titleTD.html("<span style='color:red!important'>*</span>" + titleTD.html());
        }

    }

    _isOpenRequired = typeof(isOpenRequired) == 'undefined' ? true : isOpenRequired;

    $.validator.addMethod("isNotEmpty", isNotEmpty, "");
    $.validator.addMethod("required", validateRequired, "这是必填项");
    $.validator.addMethod("maxBytes", validateMaxBytes, "最多输入{0}个字节(一个中文字占2个字节)");
    $.validator.addMethod("maxNum", validateMaxNumber, "最多输入{0}个整数,{1}个小数");
    $.validator.addMethod("isNumber", validateIsNumber, "请输入正确合法的数字");
    $.validator.addMethod("phone", phone, "请输入正确的联系电话");
    $.validator.addMethod("telephone", telephone, "请输入正确的固话号码");
    $.validator.addMethod("mobilephone", mobilephone, "请输入正确的手机号码");
    $.validator.addMethod("rule", validateRule, "");
    $.validator.addMethod("callback", validateRule, "");
    $.validator.addMethod("toggleRule", validateToggleRule, "");
    $.validator.addMethod("relate", validateRelate, "这是必填项");


    rules = rules || [];

    _validator[formId] = $("#" + formId).validate({
        rules: rules,
        formId: formId,
        errorClass: "xxxxx",
        ignore: "[ignore-data='true']",
        errorPlacement: function (error, element) {
            if (_validator[formId].validElements().index(element) > -1) {
                return;
            }
            if ($(_validator[formId].errorList[0].element).attr("name") == $(element).attr("name")) {
                var _displayElement = findDisplayElement($(element));
                if (_displayElement != null) {
                    _displayElement.addClass('redborder');
                    showErrorMsg(formId, _displayElement);
                }
            }
        },
        success: function (error, element) {
            var _displayElement = findDisplayElement($(element));
            if (_displayElement != null) {
                _displayElement.removeClass('redborder');
            }
            layer.close(_layer_index);
        },

        onfocusout: function (element) {
            $(element).valid()
        },
        onkeyup: function (element) {
            $(element).valid()
        }
    });
}
